package fstvis;

import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.util.ArrayList;

import javax.swing.JFrame;


public class FstVisualizerCli {
	public final static double DOUBLE_NULL_VALUE = -0.12345;
	protected static ArrayList<JFrame> openWindows;
	
	
	public static void main(String[] args) {
        int i = 0;
        String arg;
        boolean compareMode = false;
        Stats s, ss;
        FstData data_1, data_2;
        
        // The flags we're setting
        File file_1 = new File("/home/matt/aurams/trunk/beta/runs/run.generic/r592/bigdell2/outp/generic.r592.bigdell2.592.2010-05-11.merged.fst");
        File file_2 = new File("/home/matt/aurams/trunk/beta/runs/quick_results/emissionbf/bf_001.fst");
        String tmp, s_1 = "o3_", s_2 = "dno";
        //int time = 100, layer = 5;
        boolean plot = true;
        
        //File file_1 = new File("/dev/null"), file_2 = new File("/dev/null");
        //String tmp = new String(), s_1 = new String(), s_2 = new String();
        int time = 100, layer = 1;
        double min = DOUBLE_NULL_VALUE, max = DOUBLE_NULL_VALUE;
        boolean vflag = false;

        openWindows = new ArrayList<JFrame>();

        while (i < args.length && args[i].startsWith("-")) {
            arg = args[i++];

    // use this type of check for "wordy" arguments
            if (arg.equals("-v")) {
                System.out.println("verbose mode on");
                vflag = true;
            }

            else if (arg.equals("-min")) {
                if (i < args.length)
                    min = Double.parseDouble(args[i++]);
                else
                    System.err.println("-min requires a value");
                if (vflag)
                    System.out.println("Min value considered = " + min);
            }

            else if (arg.equals("-max")) {
                if (i < args.length)
                    max = Double.parseDouble(args[i++]);
                else
                    System.err.println("-max requires a value");
                if (vflag)
                    System.out.println("Max value considered = " + max);
            }

            else if (arg.equals("-f1")) {
                if (i < args.length) {
                    tmp = args[i++];
                    if (tmp.contains(",")) {
                    	s_1    = tmp.substring(tmp.indexOf(",") + 1);
                    	file_1 = new File(tmp.substring(0, tmp.indexOf(s_1) - 1));

                    	if (!file_1.canRead()) {
                    		System.err.println(file_1 + " is not readable");
                    		System.exit(0);
                    	}

                        if (vflag)
                            System.out.println("Reading " + s_1 + " from " + file_1);
                    	
                    } else {
                        System.err.println("-f1 requires a filename in the form <file>,<species>");
                	}
                } else
                    System.err.println("-f1 requires a filename in the form <file>,<species>");

            }

            else if (arg.equals("-f2")) {
                if (i < args.length) {
                    tmp = args[i++];
                    if (tmp.contains(",")) {
                    	s_2    = tmp.substring(tmp.indexOf(",") + 1);
                    	file_2 = new File(tmp.substring(0, tmp.indexOf(s_2) - 1));                  	

                        if (vflag)
                            System.out.println("Reading " + s_2 + " from " + file_2);
                    } else {
                        System.err.println("-f2 requires a filename in the form <file>,<species>");
                    	System.exit(0);
                	}
                }
            }

            else if (arg.equals("-t")) {
                if (i < args.length)
                    time = Integer.parseInt(args[i++]);
                else
                    System.err.println("-t requires a time value");
                if (vflag)
                    System.out.println("Time value considered = " + time);
            }

            else if (arg.equals("-l")) {
                if (i < args.length)
                    layer = Integer.parseInt(args[i++]);
                else
                    System.err.println("-l requires a layer value");
                if (vflag)
                    System.out.println("Layer value considered = " + layer);
            }
            
            else if (arg.equals("-h") || arg.equals("--help") ) {
            	System.out.println("Usage: FstVisualizerCli [-v] [-h|help] -f1 <file>,<species> -f2 <file>,<species> -t <time> -l <layer> [-min <min value>] [-max <max value>]");
            }

            else if (arg.equals("-p")) {
                plot = true;
                if (vflag)
                    System.out.println("Enabled plotting");
            }
            
    // use this type of check for a series of flag arguments
            else {
            	 System.out.println("Unrecongized input parameter " + arg);
            }
        }

        if (file_1.getAbsolutePath() == "/dev/null") {
        	System.err.println("You must specify a file to read with -f1");
        	System.exit(0);
        }
    	if (!file_1.canRead()) {
    		System.err.println("File 1 (" + file_1 + ") is not readable");
    		System.exit(0);
    	}
 	
        if (!file_2.canRead()) {
        	System.err.println("File 2 (" + file_2 + ") is not readable");
    		System.exit(0);
    	} else {
    		if (file_2.getAbsolutePath() != "/dev/null") compareMode = true;
    	}
        
        System.out.println("Processing:");
        System.out.println(s_1 + " from " + file_1);
        if (compareMode) System.out.println(s_2 + " from " + file_2);
        System.out.println("Time: " + time);
        System.out.println("Layer: " + layer);
        if (min == DOUBLE_NULL_VALUE)
        	System.out.println("No minimum value cutoff");
        else
        	System.out.println("Min cut off: " + min);

        if (max == DOUBLE_NULL_VALUE)
        	System.out.println("No max value cutoff");
        else
        	System.out.println("Max cut off: " + max);


        //////////////////////////////////////////////////////
        //
        // Alright, we're done with inputs, lets get some data
        data_1 = new FstData(file_1, s_1, time, layer);
        data_1.loadData();

        if (compareMode) {
        	data_2 = new FstData(file_2, s_2, time, layer);
        	data_2.loadData();

        	if (data_1.getField().getLength() != data_2.getField().getLength()) {
        		System.err.println("Fields are different sizes!");
        		System.exit(1);
        	} else {
        		//System.out.println("Field sizes, f1 = " + data_1.getField().getLength() + ", f2 = " + data_2.getField().getLength());
        	}

        	s = new ComparisonStats(data_1.getField(), data_2.getField());
        } else {
        	data_2 = null;
        	s = new FieldStats(data_1.getField());
        }
        System.out.println("Stats:\n" + s);

        // Use inputs or defaults?
        if (min == DOUBLE_NULL_VALUE) {
        	min = s.getMin();
        }
        if (max == DOUBLE_NULL_VALUE) {
        	max = s.getMax();
        }
        
        if (plot) {     	
       	
        	// Plot data_1
        	JFrame f1 = new PlotFrame(data_1, s, min, max);
        	attachNewWindow(f1);

        	if (compareMode) {
	        	// Plot data_2
	        	JFrame f2 = new PlotFrame(data_2, s, min, max);
	        	attachNewWindow(f2);
	
	        	// Plot data_2-data_1
	        	FstData data_diff = FstData.Difference(data_1, data_2);
	        	ss = new FieldStats(data_diff.getField());
	        	JFrame fd = new PlotFrame(data_diff, ss, ss.getMin(), ss.getMax());
	        	attachNewWindow(fd);
        	}
        }
	}
	
	private static void attachNewWindow(JFrame f) {
    	WindowListener wl = new java.awt.event.WindowAdapter() {
    		public void windowClosing(WindowEvent winEvt) {
    			FstVisualizerCli.openWindows.remove((JFrame)winEvt.getSource());
    			if (FstVisualizerCli.openWindows.isEmpty()) {
    	        	System.out.println("\nExiting...");
    				System.exit(0);
    	        }
    	    }
    	};

    	openWindows.add(f);
    	f.addWindowListener(wl);
	}
}
